package compiler.parse;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.PrintStream;
import java.util.Scanner;

import compiler.absyn.Translate;
import compiler.errormsg.ErrorMsg;
import engine.planner.CreateIndexData;
import engine.planner.CreateTableData;
import engine.planner.CreateViewData;
import engine.planner.InsertData;
import engine.planner.QueryData;
import engine.query.Plan;
import engine.query.Scan;

import server.starDB;
import storage.tx.Transaction;
public class DbParse {
	String filename;
	Translate trans;
	public ErrorMsg errormsg;
	public DbParse(String f,PrintStream out){
		filename = f;
		trans = new Translate(out);
	}
	public DbParse(){}
	public Object translate(String cmd){
		try{
			errormsg = new ErrorMsg(filename);
			InputStream input = new ByteArrayInputStream(cmd.getBytes());
			Yylex yylex = new Yylex(input,errormsg);
			parser p = new parser(yylex,errormsg);
			try{ 
				p.parse();
				return trans.trExp(p.parseResult);
			}catch(Exception e){
				System.out.print(errormsg.msg);
				e.printStackTrace();
			}
		}
		catch(Exception e){
			e.printStackTrace();
//			return null;
		}
		return null;
	}
	public static void main(String[] args){
		DbParse dbparse = new DbParse("",System.out);
		Scanner cin = new Scanner(System.in);
		starDB.init("C:\\stardb");
		String cmd;
		while(!(cmd = cin.nextLine()).equals("exit")){
			Object o = dbparse.translate(cmd);
			if(o instanceof InsertData){
				InsertData data = (InsertData)o;
				Transaction tx = new Transaction();
				int p  = starDB.planner().executeUpdate(data, tx);
				System.out.println("Insert num: "+p);
//				System.out.println(data.vals.toString());
				tx.commit();
			}
			else if(o instanceof QueryData){
				QueryData data = (QueryData)o;
				Transaction tx = new Transaction();
				Plan p  = starDB.planner().createQueryPlan(data, tx);
				Scan s = p.open();
				while(s.next()){
					System.out.println(s.getInt("num"));
				}
				tx.commit();
				System.out.println(data.fields.toString());
				System.out.println(data.tables().toString());
				System.out.println(data.subtables.toString());
				System.out.println(data.pred().toString());
			}
			else if(o instanceof CreateTableData){
				CreateTableData data = (CreateTableData)o;
				Transaction tx = new Transaction();
				int p = starDB.planner().executeUpdate(data, tx);
//				System.out.println(data.tableName());
//				System.out.println(data.newSchema().fields().toString());
				System.out.println("Update Num:"+p);
				tx.commit();
			}
			else if(o instanceof CreateViewData){
				CreateViewData data = (CreateViewData)o;
				Transaction tx = new Transaction();
				starDB.planner().executeUpdate(data, tx);
				tx.commit();
			}
			else if(o instanceof CreateIndexData){
				CreateIndexData data = (CreateIndexData)o;
				Transaction tx = new Transaction();
				starDB.planner().executeUpdate(data, tx);
				tx.commit();
			}
		}
	}
}
